#include "esp_log.h"
#include "esp_http_server.h"
#include "mycamera.h"
#include "esp_timer.h"
#include "camera_stream.h"

static const char *TAG = "CAMERA_STREAM";

// 定义视频流边界标识
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %zu\r\n\r\n";

// 处理图像请求
esp_err_t image_handler(httpd_req_t *req)
{
    ESP_LOGI(TAG, "收到图像请求");
    
    // 从摄像头获取图像
    camera_fb_t *fb = capture_image();
    if (!fb) {
        ESP_LOGE(TAG, "获取图像失败");
        httpd_resp_send_500(req);
        return ESP_FAIL;
    }
    
    // 设置HTTP响应头
    httpd_resp_set_type(req, "image/jpeg");
    httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=image.jpg");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    
    // 发送图像数据
    esp_err_t res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
    
    // 释放帧缓冲区
    return_fb_buffer(fb);
    
    ESP_LOGI(TAG, "图像已发送，大小: %d字节", fb->len);
    return res;
}

// 处理视频流请求
esp_err_t stream_handler(httpd_req_t *req)
{
    ESP_LOGI(TAG, "收到视频流请求");
    
    // 设置HTTP响应头，使用多部分混合替换格式
    httpd_resp_set_type(req, STREAM_CONTENT_TYPE);
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    
    char part_buf[64];
    int64_t last_frame = 0;
    
    // 循环发送视频帧
    while (true) {
        // 从摄像头获取图像
        camera_fb_t *fb = capture_image();
        if (!fb) {
            ESP_LOGE(TAG, "获取图像失败");
            vTaskDelay(100 / portTICK_PERIOD_MS);
            continue;
        }
        
        // 发送边界分隔符
        if (httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY)) != ESP_OK) {
            ESP_LOGI(TAG, "客户端已断开连接");
            return_fb_buffer(fb);
            break;
        }
        
        // 发送图像头信息
        size_t hlen = snprintf(part_buf, sizeof(part_buf), STREAM_PART, fb->len);
        if (httpd_resp_send_chunk(req, part_buf, hlen) != ESP_OK) {
            ESP_LOGE(TAG, "发送头部失败");
            return_fb_buffer(fb);
            break;
        }
        
        // 发送图像数据
        if (httpd_resp_send_chunk(req, (const char *)fb->buf, fb->len) != ESP_OK) {
            ESP_LOGE(TAG, "发送图像数据失败");
            return_fb_buffer(fb);
            break;
        }
        
        // 释放帧缓冲区
        return_fb_buffer(fb);
        
        // 计算帧率
        int64_t fr_end = esp_timer_get_time();
        int fps = 1000000 / (fr_end - last_frame);
        last_frame = fr_end;
        
        ESP_LOGI(TAG, "视频流帧已发送，FPS: %d", fps);
    }
    
    // 结束响应
    httpd_resp_send_chunk(req, NULL, 0);
    return ESP_OK;
}